package jfae.core.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * This annotation can be applied to a method or as a property of 
 * the annotation {@ link PropPresentation}.
 * Specifies the main guidelines of presentation
 * <ul>
 * 	<li>{@link #label()}: the label to be applied to the properties</li>
 * 	<li>{@link #fieldSize()}: the size to be applied to the form field representing properties</li>
 * 	<li>{@link #columnSize()}: allow to specify a different size value for table columns</li>
 * 	<li>{@link #fieldLength()}: the max char number allowed for corresponding form field value</li>
 * 	<li>{@link #format()}: you can specify a format string to use for presentation purpose</li>
 * 	<li>{@link #styleClass()}: html css class</li>
 * 	<li>{@link #styles()}: html styles</li>
 * </ul>
 * 
 * In the method way, simply apply {@link Presentation} to the property getter
 * then specify you preferences
 * <div class="codeblock">
 * <pre>
 * public class BaseEntity {
 * 
 * 	private String stringProp;
 * 	private Integer integerProp;
 * 	
 * 	{@code @}Editable(order=1,groupNames={"firstGroup","secondGroup"})
 *  {@code @}Presentation(
 *  		label="String Prop:", fieldSize="100", columnSize="80", 
 *  		fieldLength="80", styles="color:green;", styleClass="form_field")
 * 	public String getStringProp() {
 * 		return stringProp;
 * 	}
 * [...]
 * 	{@code @}Editable(order=2,groupNames="secondGroup")
 *  {@code @}Presentation(
 *  		label="Int Prop:", fieldSize="40", columnSize="40", 
 *  		fieldLength="3", styles="color:red;", styleClass="form_field")
 * 	public Integer getIntegerProp() {
 * 		return integerProp;
 * 	}
 * [...]
 * }
 * </pre>
 * </div>
 * or use it through {@ link PropPresentation}
 * <div class="codeblock">
 * <pre>
 * {@code @}EditableBean(exclusionNames="excludedProp", propsPresentation={
 * 		{@code @}PropPresentation(name="stringProp",order=1,
 * 				presentation={@code @}Presentation(
 *  				label="String Prop:", fieldSize="100", columnSize="80", 
 *  				fieldLength="80", styles="color:green;", styleClass="form_field")
 * 				),
 * 		{@code @}PropPresentation(name="integerProp",order=2,
 * 				presentation={@code @}Presentation(
 * 					label="Int Prop:", fieldSize="40", columnSize="40", 
 *  				fieldLength="3", styles="color:red;", styleClass="form_field")
 * 				)
 * })
 * public class BaseBean {
 * 
 * 	private String stringProp;
 * 	private Integer integerProp;
 * 	[...]
 * }
 * </pre>
 * </div>
 * 
 * Maybe you want to see something like this in form
 * <div class="codeblock">
 * <fieldset><legend>firstGroup</legend>
 * <table border="0">
 * 	<tr>
 * 		<td style="text-align:right;">String Prop:<td>
 * 		<td><input readonly="readonly" 
 * 					style="color:green;width:100px;" 
 * 					size="80" 
 * 					class="form_field" value="String prop value"/></td>
 * 	</tr>
 * 	<tr>
 * 		<td style="text-align:right;">Int Prop:<td>
 * 		<td><input readonly="readonly" 
 * 					style="color:red;width:40px;" 
 * 					size="3" 
 * 					class="form_field"  value="254"/></td>
 * 	</tr>
 * </table>
 * </fieldset>
 * </div>
 * and somthing like this in tables
 * <div class="codeblock">
 * <table cellspacing="2" cellpadding="2">
 * 	<tr>
 * 		<th style="border:1px solid red;font-weight:bold;text-align:center;width:100px;">String Prop:<th>
 * 		<th style="border:1px solid red;font-weight:bold;text-align:center;width:40px;">Int Prop:<th>
 * 	</tr>
 * 	<tr>
 * 		<td style="border:1px solid gray;color:green;width:100px;">String prop 1<td>
 * 		<td style="border:1px solid gray;color:red;width:40px;">0</td>
 * 	<tr>
 * 		<td style="border:1px solid gray;color:green;width:100px;">String prop 2<td>
 * 		<td style="border:1px solid gray;color:red;width:40px;">48</td>
 * 	<tr>
 * 		<td style="border:1px solid gray;color:green;width:100px;">String prop 3<td>
 * 		<td style="border:1px solid gray;color:red;width:40px;">63</td>
 * 	<tr>
 * 		<td style="border:1px solid gray;color:green;width:100px;">String prop 4<td>
 * 		<td style="border:1px solid gray;color:red;width:40px;">982</td>
 * 	</tr>
 * </table>
 * </div>
 * @author bobpuley
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Presentation {
	
	public static final int DEFAULT_COLUMN_SIZE = 0;
	public static final int DEFAULT_FIELD_LENGTH = 255;
	public static final int DEFAULT_FIELD_SIZE = 0;
	/**
	 * Dafult value per la label
	 */
	public static final String NO_LABEL_SET = "no_label_set";

	/**
	 * The label to be applied to the properties 
	 * @return the property label
	 */
	String label() default NO_LABEL_SET;

	/**
	 * The size to be applied to the form field representing property
	 * @return the size of form field property
	 */
	int fieldSize() default DEFAULT_FIELD_SIZE;
	/**
	 * The max char's number allowed for corresponding form field value
	 * @return a positive number representing the max number of chars allowed for this property.
	 */
	int fieldLength() default DEFAULT_FIELD_LENGTH;
	/**
	 * Dimensione della colonna associata alla proprietà
	 * @return la dimensione della colonna di ricerca. 0 se non è valorizzata
	 */
	int columnSize() default DEFAULT_COLUMN_SIZE;

	/**
	 * Gli stili da utilizzare per la view della field
	 * @return una stringa di styles
	 */
	String styles() default "";
	
	/*
	 * TODO: valutare la possibilità di estendere/decorare la FieldInfo
	 * in un modulo più specifico, in awt/swing ha poco senso
	 * Sarebbe meglio che il core implementasse solo la parte più generale
	 * il modulo html specializzerebbe poi la fieldInfo al fine di aggiungere
	 * le eventuali informazioni specifiche del dominio 
	 */
	/**
	 * I css da utilizzare per la view della field
	 * @return una stringa di css separati da spazio
	 */
	String styleClass() default "";

	/**
	 * Indica il pattern da utilizzare per formattare il valore
	 * della property, per esempio se è di tipo Date o Double
	 * @return il pattern da applicare al formatter
	 */
	String format() default "";
}
